home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / netz / term / extras / source / term-source.lha / termEmulation.c < prev    next >
C/C++ Source or Header  |  1995-07-01  |  47KB  |  2,974 lines

  1. /*
  2. **    termEmulation.c
  3. **
  4. **    Terminal emulation (parsing and processing) routines
  5. **
  6. **    Copyright © 1990-1995 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. */
  9.  
  10. #include "termGlobal.h"
  11.  
  12.     /* How many characters we will keep in the scan buffer. */
  13.  
  14. #define MAX_SCAN_SIZE    256
  15.  
  16.     /* Flag indicating whether the cursor has already been
  17.      * erased or not.
  18.      */
  19.  
  20. STATIC BYTE        CursorEnabled    = FALSE,
  21.             CursorInvisible    = FALSE;
  22.  
  23.     /* Cursor handling data. */
  24.  
  25. STATIC WORD        LastCursorX = -1,
  26.             LastCursorY = -1;
  27.  
  28. STATIC LONG        DestX,
  29.             DestY,
  30.             XSize,
  31.             FontByColumn;
  32.  
  33. STATIC BYTE        CursorGhosted = FALSE;
  34.  
  35.     /* Backup style. */
  36.  
  37. STATIC UBYTE        StyleType = FS_NORMAL;
  38.  
  39.     /* Cursor backup data. */
  40.  
  41. STATIC struct CursorData    CursorBackup;
  42. STATIC BYTE            CursorBackupValid;
  43.  
  44.     /* A couple of internally referenced variables. */
  45.  
  46. STATIC BYTE        CharsInBuffer    = 0,
  47.             ScanStep    = 0;
  48. STATIC UBYTE __far    SaveBuffer[MAX_SCAN_SIZE + 1];
  49. STATIC STRPTR        Arnie        = NULL;
  50.  
  51. STATIC BYTE        PrintFormFeed    = FALSE,
  52.             PrintFullScreen    = FALSE;
  53.  
  54.     /* UpdatePens(VOID):
  55.      *
  56.      *    Update colour and style.
  57.      */
  58.  
  59. VOID
  60. UpdatePens()
  61. {
  62.     UWORD    ForePen,
  63.         BackPen,
  64.         Attrs,
  65.         TextFlags = 0,
  66.         Mask;
  67.  
  68.         // Update the colour mask.
  69.  
  70.     switch(Config -> ScreenConfig -> ColourMode)
  71.     {
  72.         case COLOUR_AMIGA:
  73.  
  74.             Mask = MIN(DepthMask,3);
  75.  
  76.             break;
  77.  
  78.         case COLOUR_EIGHT:
  79.  
  80.             Mask = MIN(DepthMask,7);
  81.  
  82.             break;
  83.  
  84.         case COLOUR_SIXTEEN:
  85.  
  86.             Mask = MIN(DepthMask,15);
  87.  
  88.             break;
  89.  
  90.         case COLOUR_MONO:
  91.  
  92.             Mask = MIN(DepthMask,1);
  93.  
  94.             break;
  95.     }
  96.  
  97.         // Convert the colours and the text attributes
  98.  
  99.     ForePen    = PenTable[ForegroundPen];
  100.     BackPen    = PenTable[BackgroundPen];
  101.     Attrs    = TextAttributeTable[Attributes];
  102.  
  103.         // Choose a sensible colour
  104.  
  105.     if(ForePen > Mask)
  106.     {
  107.         if(BackPen > Mask)
  108.         {
  109.             if(BackPen <= ForePen)
  110.             {
  111.                 ForePen = GetPenIndex(SafeTextPen);
  112.                 BackPen = 0;
  113.             }
  114.             else
  115.             {
  116.                 ForePen = 0;
  117.                 BackPen = GetPenIndex(SafeTextPen);
  118.             }
  119.         }
  120.         else
  121.         {
  122.             if(GetPenIndex(SafeTextPen) == BackPen)
  123.                 ForePen = 0;
  124.             else
  125.                 ForePen = GetPenIndex(SafeTextPen);
  126.         }
  127.     }
  128.     else
  129.     {
  130.         if(BackPen > Mask)
  131.         {
  132.             if(!ForePen)
  133.                 BackPen = GetPenIndex(SafeTextPen);
  134.             else
  135.                 BackPen = 0;
  136.         }
  137.     }
  138.  
  139.         // Take care of the text attributes
  140.  
  141.     if(Attrs & ATTR_UNDERLINE)
  142.         TextFlags |= FSF_UNDERLINED;
  143.  
  144.     if(Attributes & ATTR_HIGHLIGHT)
  145.     {
  146.         if(Config -> ScreenConfig -> ColourMode == COLOUR_SIXTEEN)
  147.             ForePen |= 8;
  148.         else
  149.             TextFlags |= FSF_BOLD;
  150.     }
  151.  
  152.     if((Attributes & ATTR_BLINK) && (Config -> TerminalConfig -> EmulationMode == EMULATION_ANSIVT100))
  153.     {
  154.         switch(Config -> ScreenConfig -> ColourMode)
  155.         {
  156.             case COLOUR_AMIGA:
  157.  
  158.                 ForePen = 3;
  159.  
  160.                 break;
  161.  
  162.             case COLOUR_EIGHT:
  163.  
  164.                 ForePen |= 8;
  165.  
  166.                 break;
  167.  
  168.             case COLOUR_SIXTEEN:
  169.  
  170.                 if(Screen && DepthMask > 15)
  171.                     ForePen |= 16;
  172.  
  173.                 break;
  174.  
  175.             case COLOUR_MONO:
  176.  
  177.                 ForePen = GetPenIndex(SafeTextPen);
  178.  
  179.                 break;
  180.         }
  181.     }
  182.  
  183.         // Make sure that monochrome text renders properly
  184.  
  185.     if(Config -> ScreenConfig -> ColourMode == COLOUR_MONO)
  186.     {
  187.             // Out of bounds?
  188.  
  189.         if(ForePen > 1)
  190.         {
  191.                 // If it's #7 then it's white, else it's black
  192.  
  193.             if(ForePen == 7)
  194.                 ForePen = GetPenIndex(SafeTextPen);
  195.             else
  196.                 ForePen = 0;
  197.         }
  198.  
  199.         if(BackPen > 1)
  200.         {
  201.             if(BackPen == 7)
  202.                 BackPen = GetPenIndex(SafeTextPen);
  203.             else
  204.                 BackPen = 0;
  205.         }
  206.  
  207.             // Oops... the text should be readable
  208.  
  209.         if(ForePen == BackPen)
  210.         {
  211.                 // Inverse video?
  212.  
  213.             if(BackPen)
  214.             {
  215.                 ForePen = 0;
  216.                 BackPen = GetPenIndex(SafeTextPen);
  217.             }
  218.             else
  219.             {
  220.                 ForePen = GetPenIndex(SafeTextPen);
  221.                 BackPen = 0;
  222.             }
  223.         }
  224.     }
  225.  
  226.     if(Attrs & ATTR_INVERSE)
  227.     {
  228.         UWORD Help;
  229.  
  230.         Help    = ForePen;
  231.         ForePen    = BackPen;
  232.         BackPen    = Help;
  233.     }
  234.  
  235.     if(TextFlags != StyleType)
  236.     {
  237.         SetSoftStyle(RPort,TextFlags,0xFF);
  238.  
  239.         StyleType = TextFlags;
  240.     }
  241.  
  242.     FgPen = MappedPens[0][ForePen];
  243.     BgPen = MappedPens[0][BackPen];
  244.  
  245.     if(FgPen != ReadAPen(RPort))
  246.         SetAPen(RPort,FgPen);
  247.  
  248.     if(BgPen != ReadBPen(RPort))
  249.         SetBPen(RPort,BgPen);
  250. }
  251.  
  252.     /* GetFontWidth():
  253.      *
  254.      *    Get the font width of the current line.
  255.      */
  256.  
  257. WORD
  258. GetFontWidth()
  259. {
  260.     if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  261.     {
  262.         if(CurrentCharWidth == SCALE_HALF)
  263.             return((WORD)(TextFontWidth / 2));
  264.         else
  265.             return(TextFontWidth);
  266.     }
  267.     else
  268.     {
  269.         if(CurrentCharWidth == SCALE_HALF)
  270.             return(TextFontWidth);
  271.         else
  272.             return((WORD)(TextFontWidth * 2));
  273.     }
  274. }
  275.  
  276.     /* RethinkRasterLimit():
  277.      *
  278.      *    Take care of the extreme left column position
  279.      *    permitted.
  280.      */
  281.  
  282. VOID
  283. RethinkRasterLimit()
  284. {
  285.     register LONG Y;
  286.  
  287.     if(CursorY > LastLine)
  288.         Y = LastLine;
  289.     else
  290.     {
  291.         if(CursorY < 0)
  292.             Y = 0;
  293.         else
  294.             Y = CursorY;
  295.     }
  296.  
  297.     if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  298.     {
  299.         if(CurrentCharWidth == SCALE_HALF)
  300.             FontByColumn = (LastColumn + 1) * 2 - 1;
  301.         else
  302.             FontByColumn = LastColumn;
  303.     }
  304.     else
  305.     {
  306.         if(CurrentCharWidth == SCALE_HALF)
  307.             FontByColumn = LastColumn;
  308.         else
  309.             FontByColumn = ((LastColumn + 1) / 2) - 1;
  310.     }
  311. }
  312.  
  313.     /* ScrollRegion(WORD Direction):
  314.      *
  315.      *    Scroll the current scroll region up or down.
  316.      */
  317.  
  318. VOID __regargs
  319. ScrollRegion(WORD Direction)
  320. {
  321.     WORD RegionTop,RegionBottom,RegionLines;
  322.     LONG Dir,MinY,MaxY;
  323.  
  324.     if(Direction < 0)
  325.         Dir = -Direction;
  326.     else
  327.         Dir = Direction;
  328.  
  329.     if(RegionSet)
  330.     {
  331.         MinY         = MUL_Y(Top);
  332.         MaxY        = MUL_Y(Bottom + 1) - 1;
  333.  
  334.         RegionTop    = Top;
  335.         RegionBottom    = Bottom + 1;
  336.         RegionLines    = Bottom - Top + 1;
  337.     }
  338.     else
  339.     {
  340.         MinY        = 0;
  341.         MaxY         = MUL_Y(LastLine + 1) - 1;
  342.  
  343.         RegionTop    = 0;
  344.         RegionBottom    = LastLine + 1;
  345.         RegionLines    = LastLine + 1;
  346.     }
  347.  
  348.     BackupRender();
  349.  
  350.     RasterScrollRegion(Direction,RegionTop,RegionBottom,RegionLines);
  351.  
  352.     if(Config -> EmulationConfig -> ScrollMode == SCROLL_JUMP)
  353.     {
  354.         if(Dir > RegionLines)
  355.             ScrollLineRectFill(RPort,0,MinY,LastPixel,MaxY);
  356.         else
  357.         {
  358.             if(Direction > 0)
  359.                 ScrollLineRaster(RPort,0,MUL_Y(Direction),0,MinY,LastPixel,MaxY,FALSE);
  360.             else
  361.                 ScrollLineRaster(RPort,0,-MUL_Y(-Direction),0,MinY,LastPixel,MaxY,FALSE);
  362.         }
  363.     }
  364.     else
  365.     {
  366.         if(Dir > RegionLines)
  367.         {
  368.             if(Direction > 0)
  369.                 Direction = RegionLines;
  370.             else
  371.                 Direction = -RegionLines;
  372.         }
  373.  
  374.         if(Direction > 0)
  375.             ScrollLineRaster(RPort,0,MUL_Y(Direction),0,MinY,LastPixel,MaxY,TRUE);
  376.         else
  377.             ScrollLineRaster(RPort,0,-MUL_Y(-Direction),0,MinY,LastPixel,MaxY,TRUE);
  378.     }
  379.  
  380.     BackupRender();
  381. }
  382.  
  383.     /* LastChar(STRPTR Buffer):
  384.      *
  385.      *    Return the last character in a string.
  386.      */
  387.  
  388. STATIC UBYTE __inline
  389. LastChar(STRPTR Buffer)
  390. {
  391.     WORD Offset = 0;
  392.  
  393.     while(Buffer[Offset])
  394.         Offset++;
  395.  
  396.     return(Buffer[Offset - 1]);
  397. }
  398.  
  399.     /* ReadValue(STRPTR Buffer,BYTE *Value):
  400.      *
  401.      *    Parse a buffer for numbers and return a pointer
  402.      *    to the next buffer element to contain additional
  403.      *    information.
  404.      */
  405.  
  406. STATIC STRPTR __inline
  407. ReadValue(STRPTR Buffer,WORD *Value)
  408. {
  409.     while(*Buffer && *Buffer != ';' && (*Buffer < '0' || *Buffer > '9'))
  410.         Buffer++;
  411.  
  412.     if(*Buffer)
  413.     {
  414.         *Value = 0;
  415.  
  416.         while(*Buffer >= '0' && *Buffer <= '9')
  417.             *Value = (*Value * 10) + (*Buffer++ - '0');
  418.     }
  419.     else
  420.         *Value = -1;
  421.  
  422.     if(*Buffer == ';' || *Buffer == ' ')
  423.         return(Buffer + 1);
  424.     else
  425.         return(NULL);
  426. }
  427.  
  428.     /* EmulationSerWrite(STRPTR String,LONG Length):
  429.      *
  430.      *    Write text to the serial line.
  431.      */
  432.  
  433. STATIC VOID __regargs
  434. EmulationSerWrite(STRPTR String,LONG Length)
  435. {
  436.     if(SysBase -> ThisTask == SpecialQueue -> SigTask)
  437.         SerWrite(String,Length);
  438.     else
  439.     {
  440.         struct DataMsg *Msg;
  441.  
  442.         if(Length == -1)
  443.             Length = strlen(String);
  444.  
  445.         if(Msg = (struct DataMsg *)CreateMsgItem(sizeof(struct DataMsg) + Length + 1))
  446.         {
  447.             Msg -> Type = DATAMSGTYPE_WRITE;
  448.             Msg -> Data = (STRPTR)(Msg + 1);
  449.             Msg -> Size = Length;
  450.  
  451.             CopyMem(String,Msg -> Data,Length + 1);
  452.  
  453.             PutMsgItem(SpecialQueue,(struct MsgItem *)Msg);
  454.         }
  455.     }
  456. }
  457.  
  458.     /* RethinkCursorPosition():
  459.      *
  460.      *    Calculate the new cursor position.
  461.      */
  462.  
  463. STATIC VOID
  464. RethinkCursorPosition(VOID)
  465. {
  466.     if(CursorY != LastCursorY || CursorX != LastCursorX)
  467.     {
  468.         STATIC LONG X,Y;
  469.  
  470.         if(CursorY != LastCursorY)
  471.         {
  472.             if(CursorY > LastLine)
  473.                 Y = LastLine;
  474.             else
  475.             {
  476.                 if(CursorY < 0)
  477.                     Y = 0;
  478.                 else
  479.                     Y = CursorY;
  480.             }
  481.  
  482.             if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  483.             {
  484.                 if(CurrentCharWidth == SCALE_HALF)
  485.                     FontByColumn = ((LastColumn + 1) * 2) - 1;
  486.                 else
  487.                     FontByColumn = LastColumn;
  488.             }
  489.             else
  490.             {
  491.                 if(CurrentCharWidth == SCALE_HALF)
  492.                     FontByColumn = LastColumn;
  493.                 else
  494.                     FontByColumn = ((LastColumn + 1) / 2) - 1;
  495.             }
  496.  
  497.             DestY = MUL_Y(Y);
  498.  
  499.             LastCursorY = CursorY;
  500.         }
  501.  
  502.         LastCursorX = CursorX;
  503.  
  504.         if(CursorX > FontByColumn)
  505.             X = FontByColumn;
  506.         else
  507.         {
  508.             if(CursorX < 0)
  509.                 X = 0;
  510.             else
  511.                 X = CursorX;
  512.         }
  513.  
  514.         if(CurrentCharWidth == SCALE_NORMAL)
  515.         {
  516.             if(RasterAttr[Y] == SCALE_ATTR_NORMAL)
  517.             {
  518.                     // Normal width
  519.  
  520.                 DestX = MUL_X(X);
  521.                 XSize = TextFontWidth;
  522.             }
  523.             else
  524.             {
  525.                     // Double width
  526.  
  527.                 DestX = MUL_X(X) * 2;
  528.                 XSize = TextFontWidth * 2;
  529.             }
  530.         }
  531.         else
  532.         {
  533.             if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  534.             {
  535.                     // Half width
  536.  
  537.                 DestX = MUL_X(X) / 2;
  538.                 XSize = TextFontWidth / 2;
  539.             }
  540.             else
  541.             {
  542.                     // Twice the half width
  543.  
  544.                 DestX = MUL_X(X);
  545.                 XSize = TextFontWidth;
  546.             }
  547.         }
  548.     }
  549. }
  550.  
  551.     /* ToggleCursor():
  552.      *
  553.      *    (Re)draw the cursor image.
  554.      */
  555.  
  556. STATIC VOID
  557. ToggleCursor(VOID)
  558. {
  559.     if(Config -> TerminalConfig -> EmulationMode != EMULATION_EXTERNAL)
  560.     {
  561.         UWORD    OldAPen    = ReadAPen(RPort),
  562.             OldBPen    = ReadBPen(RPort),
  563.             OldDrMd    = ReadDrMd(RPort),
  564.  
  565.             Left    = WindowLeft + DestX,
  566.             Top    = WindowTop + DestY;
  567.  
  568.         if(Kick30)
  569.         {
  570.             SetABPenDrMd(RPort,DepthMask,OldBPen,JAM1 | COMPLEMENT);
  571.  
  572.             if(UseMasking)
  573.             {
  574.                 UBYTE Mask = RPort -> Mask;
  575.  
  576.                 SetMask(RPort,DepthMask);
  577.  
  578.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  579.  
  580.                 SetMask(RPort,Mask);
  581.             }
  582.             else
  583.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  584.  
  585.             SetABPenDrMd(RPort,OldAPen,OldBPen,OldDrMd);
  586.         }
  587.         else
  588.         {
  589.             SetAPen(RPort,DepthMask);
  590.             SetDrMd(RPort,JAM1 | COMPLEMENT);
  591.  
  592.             if(UseMasking)
  593.             {
  594.                 UBYTE Mask = RPort -> Mask;
  595.  
  596.                 SetMask(RPort,DepthMask);
  597.  
  598.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  599.  
  600.                 SetMask(RPort,Mask);
  601.             }
  602.             else
  603.                 RectFill(RPort,Left,Top,Left + XSize - 1,Top + TextFontHeight - 1);
  604.  
  605.             SetAPen(RPort,OldAPen);
  606.             SetDrMd(RPort,OldDrMd);
  607.         }
  608.     }
  609. }
  610.  
  611.     /* RedrawCursor():
  612.      *
  613.      *    Change the appearance of the cursor.
  614.      */
  615.  
  616. STATIC VOID
  617. RedrawCursor(VOID)
  618. {
  619.     ObtainSemaphore(&TerminalSemaphore);
  620.  
  621.     RethinkCursorPosition();
  622.  
  623.     if(CursorGhosted)
  624.     {
  625.         SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  626.  
  627.         ToggleCursor();
  628.  
  629.         SetAfPt(RPort,NULL,0);
  630.     }
  631.     else
  632.         ToggleCursor();
  633.  
  634.     ReleaseSemaphore(&TerminalSemaphore);
  635. }
  636.  
  637.     /* DoCancel():
  638.      *
  639.      *    Cancel any currently scanned sequence.
  640.      */
  641.  
  642. BYTE
  643. DoCancel()
  644. {
  645.     InSequence    = FALSE;
  646.     CharsInBuffer    = ScanStep = 0;
  647.  
  648.     return(FALSE);
  649. }
  650.  
  651.     /* CSIFake():
  652.      *
  653.      *    This routine was added to support 8-bit control
  654.      *    sequences introduced by a CSI character.
  655.      */
  656.  
  657. VOID
  658. CSIFake()
  659. {
  660.         /* Reset scanner */
  661.  
  662.     DoCancel();
  663.  
  664.         /* Perform as if ESC [ had been transmitted. */
  665.  
  666.     InSequence = ParseCode('[');
  667. }
  668.  
  669.     /* ParseCode(UBYTE c):
  670.      *
  671.      *    Input:    A character to be passed through the ANSI code
  672.      *        parser.
  673.      *
  674.      *    Output:    FALSE if input characters did form a valid ANSI
  675.      *        control sequence or if input characters did not
  676.      *        form an ANSI control sequence at all.
  677.      *
  678.      *        TRUE if input characters did possibly introduce
  679.      *        a valid ANSI control sequence.
  680.      */
  681.  
  682. BYTE
  683. ParseCode(UBYTE c)
  684. {
  685.         /* ScanStep = 0:    This is the first character
  686.          *            to introduce a control sequence.
  687.          */
  688.  
  689.     if(!ScanStep)
  690.     {
  691.         register WORD i;
  692.  
  693.             /* Scan all available codes and try to find
  694.              * a match.
  695.              */
  696.  
  697.         for(i = 0 ; i < NumCodes ; i++)
  698.         {
  699.                 /* This character may introduce a
  700.                  * control sequence.
  701.                  */
  702.  
  703.             if(ANSICode[i] . FirstChar == c)
  704.             {
  705.                     /* If this is a single
  706.                      * character control sequence
  707.                      * call the approriate function
  708.                      * and exit immediately.
  709.                      */
  710.  
  711.                 if(ANSICode[i] . ExactSize == 1)
  712.                 {
  713.                     if(Config -> TerminalConfig -> EmulationMode != EMULATION_ATOMIC)
  714.                     {
  715.                         SaveBuffer[CharsInBuffer++] = c;
  716.                         SaveBuffer[CharsInBuffer  ] = 0;
  717.  
  718.                         (*ANSICode[i] . Func)(SaveBuffer);
  719.                     }
  720.  
  721.                     CharsInBuffer = ScanStep = 0;
  722.  
  723.                     return(FALSE);
  724.                 }
  725.                 else
  726.                 {
  727.                         /* The length of this control
  728.                          * sequence is greater than
  729.                          * a single character. Save
  730.                          * the input character and
  731.                          * return.
  732.                          */
  733.  
  734.                     ScanStep = i;
  735.  
  736.                     SaveBuffer[CharsInBuffer++] = c;
  737.  
  738.                         /* Where to stop. */
  739.  
  740.                     Arnie = ANSICode[i] . Terminator;
  741.  
  742.                     return(TRUE);
  743.                 }
  744.             }
  745.         }
  746.     }
  747.     else
  748.     {
  749.         if(CharsInBuffer < MAX_SCAN_SIZE)
  750.         {
  751.             if(Arnie)
  752.             {
  753.                 register WORD i;
  754.  
  755.                     /* Scan the remaining codes for a match. */
  756.  
  757.                 for(i = ScanStep ; i < NumCodes ; i++)
  758.                 {
  759.                         /* This sequence begins with the
  760.                          * same character the parser was
  761.                          * initialized with, so let's take
  762.                          * a look at it.
  763.                          */
  764.  
  765.                     if(ANSICode[i] . FirstChar == SaveBuffer[0])
  766.                     {
  767.                             /* This character is supposed to
  768.                              * terminate the sequence, so exit.
  769.                              */
  770.  
  771.                         if(Arnie[c])
  772.                         {
  773.                             if(Config -> TerminalConfig -> EmulationMode != EMULATION_ATOMIC)
  774.                             {
  775.                                 SaveBuffer[CharsInBuffer++] = c;
  776.                                 SaveBuffer[CharsInBuffer  ] = 0;
  777.  
  778.                                 (*ANSICode[i] . Func)(SaveBuffer);
  779.                             }
  780.  
  781.                             CharsInBuffer = ScanStep = 0;
  782.  
  783.                             Arnie = NULL;
  784.  
  785.                             return(FALSE);
  786.                         }
  787.                         else
  788.                         {
  789.                                 /* If this character is part of
  790.                                  * a legal sequence store it
  791.                                  * and return.
  792.                                  */
  793.  
  794.                             if(ANSICode[i] . Match[c])
  795.                             {
  796.                                 ScanStep = i;
  797.  
  798.                                 SaveBuffer[CharsInBuffer++] = c;
  799.  
  800.                                 return(TRUE);
  801.                             }
  802.                         }
  803.                     }
  804.                 }
  805.             }
  806.             else
  807.             {
  808.                 register WORD i;
  809.  
  810.                 for(i = ScanStep ; i < NumCodes ; i++)
  811.                 {
  812.                         /* This sequence begins with the
  813.                          * same character the parser was
  814.                          * initialized with, so let's take
  815.                          * a look at it.
  816.                          */
  817.  
  818.                     if(ANSICode[i] . FirstChar == SaveBuffer[0])
  819.                     {
  820.                             /* This character is supposed to
  821.                              * terminate the sequence, so exit.
  822.                              */
  823.  
  824.                         if(ANSICode[i] . LastChar == c)
  825.                         {
  826.                             if(Config -> TerminalConfig -> EmulationMode != EMULATION_ATOMIC)
  827.                             {
  828.                                 SaveBuffer[CharsInBuffer++] = c;
  829.                                 SaveBuffer[CharsInBuffer  ] = 0;
  830.  
  831.                                 (*ANSICode[i] . Func)(SaveBuffer);
  832.                             }
  833.  
  834.                             CharsInBuffer = ScanStep = 0;
  835.  
  836.                             return(FALSE);
  837.                         }
  838.                         else
  839.                         {
  840.                                 /* If this character is part of
  841.                                  * a legal sequence store it
  842.                                  * and return.
  843.                                  */
  844.  
  845.                             if(ANSICode[i] . Match[c])
  846.                             {
  847.                                 ScanStep = i;
  848.  
  849.                                 SaveBuffer[CharsInBuffer++] = c;
  850.  
  851.                                 return(TRUE);
  852.                             }
  853.                         }
  854.                     }
  855.                 }
  856.             }
  857.         }
  858.     }
  859.  
  860.         /* Return failure. */
  861.  
  862.     CharsInBuffer = ScanStep = 0;
  863.  
  864.     Arnie = NULL;
  865.  
  866.     return(FALSE);
  867. }
  868.  
  869.     /* NormalCursor():
  870.      *
  871.      *    Enable normal (filled) cursor image.
  872.      */
  873.  
  874. VOID
  875. NormalCursor()
  876. {
  877.     ObtainSemaphore(&TerminalSemaphore);
  878.  
  879.     if(CursorGhosted)
  880.     {
  881.         if(CursorEnabled && !CursorInvisible)
  882.         {
  883.             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  884.  
  885.             ToggleCursor();
  886.  
  887.             SetAfPt(RPort,NULL,0);
  888.  
  889.             ToggleCursor();
  890.         }
  891.  
  892.         CursorGhosted = FALSE;
  893.     }
  894.  
  895.     ReleaseSemaphore(&TerminalSemaphore);
  896. }
  897.  
  898.     /* GhostCursor():
  899.      *
  900.      *    Enable ghosted (checkered) cursor image.
  901.      */
  902.  
  903. VOID
  904. GhostCursor()
  905. {
  906.     ObtainSemaphore(&TerminalSemaphore);
  907.  
  908.     if(!CursorGhosted)
  909.     {
  910.         if(CursorEnabled && !CursorInvisible)
  911.         {
  912.             ToggleCursor();
  913.  
  914.             SetAfPt(RPort,(UWORD *)&Crosshatch,1);
  915.  
  916.             ToggleCursor();
  917.  
  918.             SetAfPt(RPort,NULL,0);
  919.         }
  920.  
  921.         CursorGhosted = TRUE;
  922.     }
  923.  
  924.     ReleaseSemaphore(&TerminalSemaphore);
  925. }
  926.  
  927.     /* RepositionCursor():
  928.      *
  929.      *    Redraw the cursor at the new position.
  930.      */
  931.  
  932. VOID
  933. RepositionCursor()
  934. {
  935.     ObtainSemaphore(&TerminalSemaphore);
  936.  
  937.     RethinkCursorPosition();
  938.  
  939.     Move(RPort,WindowLeft + DestX,WindowTop + DestY + TextFontBase);
  940.  
  941.     ReleaseSemaphore(&TerminalSemaphore);
  942. }
  943.  
  944.     /* ClearCursor():
  945.      *
  946.      *    Clear the cursor image.
  947.      */
  948.  
  949. VOID
  950. ClearCursor()
  951. {
  952.     ObtainSemaphore(&TerminalSemaphore);
  953.  
  954.     if(CursorEnabled && !CursorInvisible)
  955.     {
  956.         RedrawCursor();
  957.  
  958.         CursorEnabled = FALSE;
  959.     }
  960.  
  961.     ReleaseSemaphore(&TerminalSemaphore);
  962. }
  963.  
  964.     /* DrawCursor():
  965.      *
  966.      *    Explicitely (re-)draw the cursor image.
  967.      */
  968.  
  969. VOID
  970. DrawCursor()
  971. {
  972.     ObtainSemaphore(&TerminalSemaphore);
  973.  
  974.     if(!CursorEnabled && !CursorInvisible)
  975.     {
  976.         RedrawCursor();
  977.  
  978.         CursorEnabled = TRUE;
  979.     }
  980.  
  981.     ReleaseSemaphore(&TerminalSemaphore);
  982. }
  983.  
  984.     /* BackupRender():
  985.      *
  986.      *    Save current draw modes, pen and position or restore
  987.      *    the data.
  988.      */
  989.  
  990. VOID
  991. BackupRender()
  992. {
  993.     STATIC BYTE    Called = FALSE;
  994.     STATIC UBYTE    DrMd,
  995.             FgPen,
  996.             BgPen;
  997.     STATIC UWORD    OldX,OldY;
  998.     STATIC UBYTE    Style;
  999.  
  1000.     if(!Called)
  1001.     {
  1002.         DrMd    = ReadDrMd(RPort);
  1003.         FgPen    = ReadAPen(RPort);
  1004.         BgPen    = ReadBPen(RPort);
  1005.  
  1006.         OldX    = RPort -> cp_x - WindowLeft;
  1007.         OldY    = RPort -> cp_y - WindowTop;
  1008.  
  1009.         Style    = StyleType;
  1010.  
  1011.         Called    = TRUE;
  1012.     }
  1013.     else
  1014.     {
  1015.         if(ReadDrMd(RPort) != DrMd)
  1016.             SetDrMd(RPort,DrMd);
  1017.  
  1018.         if(ReadAPen(RPort) != FgPen)
  1019.             SetAPen(RPort,FgPen);
  1020.  
  1021.         if(ReadBPen(RPort) != BgPen)
  1022.             SetBPen(RPort,BgPen);
  1023.  
  1024.         Move(RPort,OldX + WindowLeft,OldY + WindowTop);
  1025.  
  1026.         if(Style != StyleType)
  1027.         {
  1028.             SetSoftStyle(RPort,Style,0xFF);
  1029.  
  1030.             StyleType = Style;
  1031.         }
  1032.  
  1033.         Called = FALSE;
  1034.     }
  1035. }
  1036.  
  1037.     /* ShiftChar(LONG Size):
  1038.      *
  1039.      *    Simulate character insertion at the current cursor
  1040.      *    position by shifting the whole line Size times eight pixels
  1041.      *    to the right.
  1042.      */
  1043.  
  1044. VOID __regargs
  1045. ShiftChar(LONG Size)
  1046. {
  1047.     LONG DeltaX,MinX,MinY;
  1048.  
  1049.     MinY = MUL_Y(CursorY);
  1050.  
  1051.     if(CurrentCharWidth == SCALE_NORMAL)
  1052.     {
  1053.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  1054.         {
  1055.             DeltaX    = MUL_X(Size);
  1056.             MinX    = MUL_X(CursorX);
  1057.         }
  1058.         else
  1059.         {
  1060.             DeltaX    = MUL_X(Size) * 2;
  1061.             MinX    = MUL_X(CursorX) * 2;
  1062.         }
  1063.     }
  1064.     else
  1065.     {
  1066.         if(RasterAttr[CursorY] == SCALE_ATTR_NORMAL)
  1067.         {
  1068.             DeltaX    = MUL_X(Size) / 2;
  1069.             MinX    = MUL_X(CursorX) / 2;
  1070.         }
  1071.         else
  1072.         {
  1073.             DeltaX    = MUL_X(Size);
  1074.             MinX    = MUL_X(CursorX);
  1075.         }
  1076.     }
  1077.  
  1078.     if(MinX < WindowWidth)
  1079.     {
  1080.         BackupRender();
  1081.  
  1082.         ScrollLineRasterNoTabChange(RPort,-DeltaX,0,MinX,MinY,LastPixel,MinY + TextFontHeight - 1,FALSE);
  1083.  
  1084.         BackupRender();
  1085.     }
  1086. }
  1087.  
  1088.     /* Ignore():
  1089.      *
  1090.      *    Do nothing, return immediately.
  1091.      */
  1092.  
  1093. VOID
  1094. Ignore()
  1095. {
  1096. }
  1097.  
  1098.     /* ScrollDown(STRPTR Buffer):
  1099.      *
  1100.      *    Scroll the current region down.
  1101.      */
  1102.  
  1103. VOID
  1104. ScrollDown(STRPTR Buffer)
  1105. {
  1106.     WORD Value;
  1107.  
  1108.     ReadValue(Buffer,&Value);
  1109.  
  1110.     if(Value < 1)
  1111.         Value = 1;
  1112.  
  1113.     ScrollRegion(-Value);
  1114. }
  1115.  
  1116.     /* ScrollUp(STRPTR Buffer):
  1117.      *
  1118.      *    Scroll the current region up.
  1119.      */
  1120.  
  1121. VOID
  1122. ScrollUp(STRPTR Buffer)
  1123. {
  1124.     WORD Value;
  1125.  
  1126.     ReadValue(Buffer,&Value);
  1127.  
  1128.     if(Value < 1)
  1129.         Value = 1;
  1130.  
  1131.     ScrollRegion(Value);
  1132. }
  1133.  
  1134.     /* CursorScrollDown():
  1135.      *
  1136.      *    Move cursor down and scroll region if necessary.
  1137.      */
  1138.  
  1139. VOID
  1140. CursorScrollDown()
  1141. {
  1142.     DownLine();
  1143.  
  1144.     RepositionCursor();
  1145. }
  1146.  
  1147. VOID
  1148. DownLine()
  1149. {
  1150.     UBYTE InRegion = TRUE;
  1151.     WORD  Hit      = LastLine;
  1152.  
  1153.     if(RegionSet)
  1154.     {
  1155.         if(CursorY <= Bottom)
  1156.             Hit = Bottom;
  1157.         else
  1158.             InRegion = FALSE;
  1159.     }
  1160.  
  1161.     if(CursorY == Hit)
  1162.     {
  1163.         if(InRegion)
  1164.             ScrollRegion(1);
  1165.     }
  1166.     else
  1167.     {
  1168.         CursorY++;
  1169.  
  1170.         if(CursorY > LastLine)
  1171.             CursorY = LastLine;
  1172.  
  1173.         ConFontScaleUpdate();
  1174.     }
  1175. }
  1176.  
  1177.     /* CursorScrollUp():
  1178.      *
  1179.      *    Move cursor up and scroll region if necessary.
  1180.      */
  1181.  
  1182. VOID
  1183. CursorScrollUp()
  1184. {
  1185.     BYTE InRegion    = TRUE;
  1186.     WORD Hit    = 0;
  1187.  
  1188.     if(RegionSet)
  1189.     {
  1190.         if(CursorY >= Top)
  1191.             Hit = Top;
  1192.         else
  1193.             InRegion = FALSE;
  1194.     }
  1195.  
  1196.     if(CursorY == Hit)
  1197.     {
  1198.         if(InRegion)
  1199.             ScrollRegion(-1);
  1200.     }
  1201.     else
  1202.     {
  1203.         if(--CursorY < 0)
  1204.             CursorY = 0;
  1205.  
  1206.         ConFontScaleUpdate();
  1207.     }
  1208.  
  1209.     RepositionCursor();
  1210. }
  1211.  
  1212.     /* NextLine():
  1213.      *
  1214.      *    Do something like CR+LF.
  1215.      */
  1216.  
  1217. VOID
  1218. NextLine()
  1219. {
  1220.     CursorX = 0;
  1221.  
  1222.     DownLine();
  1223.  
  1224.     RepositionCursor();
  1225. }
  1226.  
  1227.     /* SaveCursor():
  1228.      *
  1229.      *    Save cursor position and rendering attributes.
  1230.      */
  1231.  
  1232. VOID
  1233. SaveCursor()
  1234. {
  1235.     CursorBackup . Charset        = Charset;
  1236.     CursorBackup . Attributes    = Attributes;
  1237.     CursorBackup . CursorX        = CursorX;
  1238.     CursorBackup . CursorY        = CursorY;
  1239.     CursorBackup . Style        = StyleType;
  1240.     CursorBackup . FgPen        = ForegroundPen;
  1241.     CursorBackup . BgPen        = BackgroundPen;
  1242.     CursorBackup . CurrentFont    = CurrentFont;
  1243.     CursorBackup . CharMode[0]    = CharMode[0];
  1244.     CursorBackup . CharMode[1]    = CharMode[1];
  1245.  
  1246.     CursorBackupValid = TRUE;
  1247. }
  1248.  
  1249.     /* FontStuff(STRPTR Buffer):
  1250.      *
  1251.      *    Set the drawing font (standard characters/line).
  1252.      */
  1253.  
  1254. VOID
  1255. FontStuff(STRPTR Buffer)
  1256. {
  1257.     BYTE Changed = FALSE;
  1258.  
  1259.     if(Buffer[0] == '(')
  1260.     {
  1261.         switch(LastChar(Buffer))
  1262.         {
  1263.             case 'A':
  1264.             case 'B':
  1265.  
  1266.                 if(CharMode[0] != TABLE_ASCII && !Charset)
  1267.                     Changed = TRUE;
  1268.  
  1269.                 CharMode[0] = TABLE_ASCII;
  1270.  
  1271.                 break;
  1272.  
  1273.             case '0':
  1274.  
  1275.                 if(CharMode[0] != TABLE_GFX && !Charset)
  1276.                     Changed = TRUE;
  1277.  
  1278.                 CharMode[0] = TABLE_GFX;
  1279.  
  1280.                 break;
  1281.         }
  1282.     }
  1283.  
  1284.     if(Buffer[0] == ')')
  1285.     {
  1286.         switch(LastChar(Buffer))
  1287.         {
  1288.             case 'A':
  1289.             case 'B':
  1290.  
  1291.                 if(CharMode[1] != TABLE_ASCII && Charset == 1)
  1292.                     Changed = TRUE;
  1293.  
  1294.                 CharMode[1] = TABLE_ASCII;
  1295.  
  1296.                 break;
  1297.  
  1298.             case '0':
  1299.  
  1300.                 if(CharMode[1] != TABLE_GFX && Charset == 1)
  1301.                     Changed = TRUE;
  1302.  
  1303.                 CharMode[1] = TABLE_GFX;
  1304.  
  1305.                 break;
  1306.         }
  1307.     }
  1308.  
  1309.     if(Changed)
  1310.     {
  1311.         BackupRender();
  1312.  
  1313.         if(Charset)
  1314.             DoShiftIn();
  1315.         else
  1316.             DoShiftOut();
  1317.  
  1318.         BackupRender();
  1319.     }
  1320. }
  1321.  
  1322.     /* LoadCursor():
  1323.      *
  1324.      *    Load cursor position and rendering attributes.
  1325.      */
  1326.  
  1327. VOID
  1328. LoadCursor()
  1329. {
  1330.     Charset        = CursorBackup . Charset;
  1331.  
  1332.     CharMode[0]    = CursorBackup . CharMode[0];
  1333.     CharMode[1]    = CursorBackup . CharMode[1];
  1334.  
  1335.     if(CurrentFont != CursorBackup . CurrentFont)
  1336.     {
  1337.         CurrentFont = CursorBackup . CurrentFont;
  1338.  
  1339.         SetFont(RPort,CurrentFont);
  1340.  
  1341.         ConOutputUpdate();
  1342.     }
  1343.  
  1344.     ForegroundPen    = CursorBackup . FgPen;
  1345.     BackgroundPen    = CursorBackup . BgPen;
  1346.     Attributes    = CursorBackup . Attributes;
  1347.     CursorX        = CursorBackup . CursorX;
  1348.     CursorY        = CursorBackup . CursorY;
  1349.  
  1350.     UpdatePens();
  1351.  
  1352.     ConFontScaleUpdate();
  1353.  
  1354.     RepositionCursor();
  1355. }
  1356.  
  1357.     /* ScaleFont(STRPTR Buffer):
  1358.      *
  1359.      *    Select a new font scale.
  1360.      */
  1361.  
  1362. VOID
  1363. ScaleFont(STRPTR Buffer)
  1364. {
  1365.     if(!Config -> EmulationConfig -> FontLocked)
  1366.     {
  1367.         WORD NewScale,Scale;
  1368.  
  1369.         Scale = RasterAttr[CursorY];
  1370.  
  1371.         NewScale = Scale;
  1372.  
  1373.         switch(LastChar(Buffer))
  1374.         {
  1375.             case '3':
  1376.  
  1377.                 NewScale = SCALE_ATTR_TOP2X;
  1378.  
  1379.                 break;
  1380.  
  1381.             case '4':
  1382.  
  1383.                 NewScale = SCALE_ATTR_BOT2X;
  1384.  
  1385.                 break;
  1386.  
  1387.             case '5':
  1388.  
  1389.                 NewScale = SCALE_NORMAL;
  1390.  
  1391.                 break;
  1392.  
  1393.             case '6':
  1394.  
  1395.                 NewScale = SCALE_ATTR_2X;
  1396.  
  1397.                 break;
  1398.         }
  1399.  
  1400.         if(Scale != NewScale)
  1401.         {
  1402.             UBYTE    *RasterPtr    = &Raster[CursorY * RasterWidth];
  1403.             WORD     RightMargin    = LastColumn + 1,
  1404.                  CursorXSave    = CursorX;
  1405.  
  1406.             if(NewScale != SCALE_ATTR_NORMAL)
  1407.             {
  1408.                     // Twice the normal character width
  1409.  
  1410.                 if(CurrentCharWidth == SCALE_NORMAL)
  1411.                     RightMargin /= 2;
  1412.             }
  1413.             else
  1414.             {
  1415.                     // Half the normal character width
  1416.  
  1417.                 if(CurrentCharWidth != SCALE_NORMAL)
  1418.                     RightMargin *= 2;
  1419.             }
  1420.  
  1421.             RasterAttr[CursorY] = NewScale;
  1422.  
  1423.             RethinkRasterLimit();
  1424.  
  1425.             ConFontScaleUpdate();
  1426.  
  1427.             if(FontScalingRequired)
  1428.             {
  1429.                 CursorX = 0;
  1430.  
  1431.                 PrintScaled(RasterPtr,RightMargin,NewScale);
  1432.             }
  1433.             else
  1434.             {
  1435.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(CursorY) + TextFontBase);
  1436.                 Text(RPort,RasterPtr,RightMargin);
  1437.             }
  1438.  
  1439.             if(CursorXSave >= RightMargin)
  1440.                 CursorX = RightMargin - 1;
  1441.             else
  1442.                 CursorX = CursorXSave;
  1443.         }
  1444.  
  1445.         RepositionCursor();
  1446.     }
  1447. }
  1448.  
  1449.     /* AlignmentTest():
  1450.      *
  1451.      *    Perform screen alignment test, fill the screen with `E's.
  1452.      */
  1453.  
  1454. VOID
  1455. AlignmentTest()
  1456. {
  1457.     STRPTR Buffer;
  1458.  
  1459.     if(Buffer = AllocVecPooled(LastColumn + 1,MEMF_ANY))
  1460.     {
  1461.         WORD i;
  1462.  
  1463.         memset(Buffer,'E',LastColumn + 1);
  1464.  
  1465.         EraseScreen("2");
  1466.  
  1467.         if(FontScalingRequired)
  1468.         {
  1469.             for(i = 0 ; i <= LastLine ; i++)
  1470.             {
  1471.                 CursorX = 0;
  1472.                 CursorY = i;
  1473.  
  1474.                 RasterAttr[i] = SCALE_ATTR_NORMAL;
  1475.  
  1476.                 RasterPutString(Buffer,LastColumn + 1);
  1477.                 ScrollLinePutString(LastColumn + 1);
  1478.  
  1479.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(i) + TextFontBase);
  1480.                 PrintScaled(Buffer,LastColumn + 1,SCALE_ATTR_NORMAL);
  1481.             }
  1482.         }
  1483.         else
  1484.         {
  1485.             for(i = 0 ; i <= LastLine ; i++)
  1486.             {
  1487.                 CursorX = 0;
  1488.                 CursorY = i;
  1489.  
  1490.                 RasterPutString(Buffer,LastColumn + 1);
  1491.                 ScrollLinePutString(LastColumn + 1);
  1492.  
  1493.                 Move(RPort,WindowLeft,WindowTop + MUL_Y(i) + TextFontBase);
  1494.                 Text(RPort,Buffer,LastColumn + 1);
  1495.             }
  1496.         }
  1497.  
  1498.         CursorX = CursorY = 0;
  1499.  
  1500.         RethinkRasterLimit();
  1501.  
  1502.         RepositionCursor();
  1503.  
  1504.         FreeVecPooled(Buffer);
  1505.  
  1506.         ConFontScaleUpdate();
  1507.     }
  1508. }
  1509.  
  1510.     /* SetTab():
  1511.      *
  1512.      *    Set a tabulator stop at the current position.
  1513.      */
  1514.  
  1515. VOID
  1516. SetTab()
  1517. {
  1518.     if(CursorX < TabStopMax)
  1519.         TabStops[CursorX] = TRUE;
  1520. }
  1521.  
  1522.     /* RequestTerminal(STRPTR Buffer):
  1523.      *
  1524.      *    Return the current terminal position.
  1525.      */
  1526.  
  1527. VOID
  1528. RequestTerminal(STRPTR Buffer)
  1529. {
  1530.     switch(Buffer[0])
  1531.     {
  1532.             /* Make ourselves known as a VT200
  1533.              * terminal.
  1534.              */
  1535.  
  1536.         case '[':
  1537.  
  1538.             if(Buffer[1] != '>')
  1539.                 EmulationSerWrite("\033[?62;1;2;6;7;8;9c",-1);
  1540.             else
  1541.                 EmulationSerWrite("\033[>1;10;0c",-1);
  1542.  
  1543.             break;
  1544.  
  1545.             /* This is an old status request type,
  1546.              * we will return the standard `I am a
  1547.              * VT101' sequence.
  1548.              */
  1549.  
  1550.         case 'Z':
  1551.  
  1552.             EmulationSerWrite("\033[?1;0c",-1);
  1553.             break;
  1554.     }
  1555. }
  1556.  
  1557.     /* SoftReset():
  1558.      *
  1559.      *    Plain and simple: reset the text rendering colours, style and the
  1560.      *    font being used. This works similar to the Reset() call which
  1561.      *    also clears the screen.
  1562.      */
  1563.  
  1564. VOID
  1565. SoftReset()
  1566. {
  1567.     ObtainSemaphore(&TerminalSemaphore);
  1568.  
  1569.         /* Are we running on an external emulation? */
  1570.  
  1571.     if(XEmulatorBase && Config -> TerminalConfig -> EmulationMode == EMULATION_EXTERNAL)
  1572.     {
  1573.         XEmulatorResetTextStyles(XEM_IO);
  1574.         XEmulatorResetCharset(XEM_IO);
  1575.     }
  1576.     else
  1577.     {
  1578.         if(!Config -> EmulationConfig -> FontLocked)
  1579.             CurrentCharWidth = SCALE_NORMAL;
  1580.  
  1581.             /* Reset the text rendering colours. */
  1582.  
  1583.         if(!Config -> EmulationConfig -> LockColour)
  1584.         {
  1585.             ForegroundPen = GetPenIndex(SafeTextPen);
  1586.             BackgroundPen = 0;
  1587.         }
  1588.  
  1589.         if(StyleType != FS_NORMAL && !Config -> EmulationConfig -> LockStyle)
  1590.             StyleType = FS_NORMAL;
  1591.  
  1592.         ConFontScaleUpdate();
  1593.  
  1594.         UpdatePens();
  1595.  
  1596.         SetMask(RPort,DepthMask);
  1597.  
  1598.         CurrentFont = TextFont;
  1599.  
  1600.         SetFont(RPort,CurrentFont);
  1601.  
  1602.         ConOutputUpdate();
  1603.  
  1604.         CursorBackupValid = FALSE;
  1605.     }
  1606.  
  1607.     ReleaseSemaphore(&TerminalSemaphore);
  1608. }
  1609.  
  1610.     /* Reset():
  1611.      *
  1612.      *    Reset terminal to initial state.
  1613.      */
  1614.  
  1615. VOID
  1616. Reset()
  1617. {
  1618.     LONG    MaxColumns,MaxLines,
  1619.         Columns,Lines,
  1620.         i;
  1621.  
  1622.     ObtainSemaphore(&TerminalSemaphore);
  1623.  
  1624.     CursorEnabled = CursorInvisible = FALSE;
  1625.  
  1626.     if(Window -> Flags & WFLG_WINDOWACTIVE)
  1627.         CursorGhosted = FALSE;
  1628.     else
  1629.         CursorGhosted = TRUE;
  1630.  
  1631.         /* Determine window inner dimensions and top/left edge offsets. */
  1632.  
  1633.     UpdateTerminalLimits();
  1634.  
  1635.     MaxColumns    = WindowWidth / TextFontWidth;
  1636.     MaxLines    = WindowHeight / TextFontHeight;
  1637.  
  1638.         /* Set up the new screen width. */
  1639.  
  1640.     if(Config -> TerminalConfig -> NumColumns < 20)
  1641.         Columns = MaxColumns;
  1642.     else
  1643.         Columns = Config -> TerminalConfig -> NumColumns;
  1644.  
  1645.         /* Set up the new screen height. */
  1646.  
  1647.     if(Config -> TerminalConfig -> NumLines < 20)
  1648.         Lines = MaxLines;
  1649.     else
  1650.         Lines = Config -> TerminalConfig -> NumLines;
  1651.  
  1652.         /* More columns than we will be able to display? */
  1653.  
  1654.     if(Columns > MaxColumns)
  1655.         Columns = MaxColumns;
  1656.  
  1657.         /* More lines than we will be able to display? */
  1658.  
  1659.     if(Lines > MaxLines)
  1660.         Lines = MaxLines;
  1661.  
  1662.         /* Set up the central data. */
  1663.  
  1664.     LastColumn    = Columns - 1;
  1665.     LastLine    = Lines - 1;
  1666.     LastPixel    = MUL_X(Columns) - 1;
  1667.  
  1668.     for(i = 0 ; i <= LastLine ; i++)
  1669.         RasterAttr[i] = SCALE_ATTR_NORMAL;
  1670.  
  1671.     memset(TabStops,FALSE,TabStopMax);
  1672.  
  1673.     for(i = 8 ; i < TabStopMax ; i += 8)
  1674.         TabStops[i] = TRUE;
  1675.  
  1676.     CharMode[0] = TABLE_ASCII;
  1677.     CharMode[1] = TABLE_GFX;
  1678.  
  1679.     Charset = 0;
  1680.  
  1681.     SetAPen(RPort,MappedPens[0][PenTable[0]]);
  1682.  
  1683.     SetMask(RPort,DepthMask);
  1684.  
  1685.     RectFill(RPort,WindowLeft,WindowTop,WindowLeft + WindowWidth - 1,WindowTop + WindowHeight - 1);
  1686.  
  1687.     ScrollLineEraseScreen(2);
  1688.  
  1689.     RasterEraseScreen(2);
  1690.  
  1691.     if(!Config -> EmulationConfig -> LockColour)
  1692.     {
  1693.         ForegroundPen = GetPenIndex(SafeTextPen);
  1694.         BackgroundPen = 0;
  1695.     }
  1696.  
  1697.     if(StyleType != FS_NORMAL && !Config -> EmulationConfig -> LockStyle)
  1698.         StyleType = FS_NORMAL;
  1699.  
  1700.     UpdatePens();
  1701.  
  1702.     CurrentFont = TextFont;
  1703.  
  1704.     SetFont(RPort,CurrentFont);
  1705.  
  1706.     ConOutputUpdate();
  1707.  
  1708.     UseRegion = FALSE;
  1709.     RegionSet = FALSE;
  1710.  
  1711.     if(!Config -> EmulationConfig -> CursorLocked)
  1712.         Config -> EmulationConfig -> CursorMode = KEYMODE_STANDARD;
  1713.  
  1714.     if(!Config -> EmulationConfig -> KeysLocked)
  1715.         Config -> EmulationConfig -> NumericMode = KEYMODE_STANDARD;
  1716.  
  1717.     Config -> EmulationConfig -> NewLineMode    = FALSE;
  1718.     Config -> EmulationConfig -> InsertMode        = FALSE;
  1719.     Config -> EmulationConfig -> ScrollMode        = SCROLL_JUMP;
  1720.  
  1721.     if(!Config -> EmulationConfig -> LockWrapping)
  1722.         Config -> EmulationConfig -> LineWrap = TRUE;
  1723.  
  1724.     if(!Config -> EmulationConfig -> FontLocked)
  1725.         CurrentCharWidth = SCALE_NORMAL;
  1726.  
  1727.     if(!Config -> EmulationConfig -> LockStyle)
  1728.         Attributes = 0;
  1729.  
  1730.     Top        = 0;
  1731.     Bottom        = LastLine;
  1732.     CursorX        = 0;
  1733.     CursorY        = 0;
  1734.  
  1735.     CursorBackup . Charset        = Charset;
  1736.     CursorBackup . Attributes    = Attributes;
  1737.     CursorBackup . CursorX        = CursorX;
  1738.     CursorBackup . CursorY        = CursorY;
  1739.     CursorBackup . Style        = StyleType;
  1740.     CursorBackup . FgPen        = ForegroundPen;
  1741.     CursorBackup . BgPen        = BackgroundPen;
  1742.     CursorBackup . CurrentFont    = CurrentFont;
  1743.     CursorBackup . CharMode[0]    = CharMode[0];
  1744.     CursorBackup . CharMode[1]    = CharMode[1];
  1745.  
  1746.     CursorBackupValid = FALSE;
  1747.  
  1748.     ConFontScaleUpdate();
  1749.  
  1750.     RepositionCursor();
  1751.  
  1752.     ReleaseSemaphore(&TerminalSemaphore);
  1753. }
  1754.  
  1755.     /* PrinterController(STRPTR Buffer):
  1756.      *
  1757.      *    Controls various screen dump and capture functions.
  1758.      */
  1759.  
  1760. VOID
  1761. PrinterController(STRPTR Buffer)
  1762. {
  1763.     if(Config -> EmulationConfig -> PrinterEnabled)
  1764.     {
  1765.         switch(Buffer[1])
  1766.         {
  1767.             case 'i':    // Print screen
  1768.             case '0':
  1769.  
  1770.                 if(PrintFullScreen)
  1771.                     PrintRegion(0,LastLine + 1,PrintFormFeed);
  1772.                 else
  1773.                     PrintRegion(Top,Bottom + 1,PrintFormFeed);
  1774.  
  1775.                 break;
  1776.  
  1777.             case '5':    // Turn on printer controller mode
  1778.  
  1779.                 OpenPrinterCapture(TRUE);
  1780.                 break;
  1781.  
  1782.             case '4':    // Turn off printer controller mode
  1783.  
  1784.                 ClosePrinterCapture(FALSE);
  1785.                 break;
  1786.  
  1787.             case '?':
  1788.  
  1789.                 if(Buffer[2] == '1')    // Print current line
  1790.                     PrintRegion(CursorY,CursorY + 1,FALSE);
  1791.  
  1792.                 if(Buffer[2] == '5')    // Turn on auto print mode
  1793.                     OpenPrinterCapture(FALSE);
  1794.  
  1795.                 if(Buffer[2] == '4')    // Turn off auto print mode
  1796.                     ClosePrinterCapture(FALSE);
  1797.  
  1798.                 break;
  1799.         }
  1800.     }
  1801. }
  1802.  
  1803.     /* RequestInformation(STRPTR Buffer):
  1804.      *
  1805.      *    Request miscellaneous information (state & cursor position).
  1806.      */
  1807.  
  1808. VOID
  1809. RequestInformation(STRPTR Buffer)
  1810. {
  1811.     UBYTE    LocalBuffer[40];
  1812.     WORD    Value;
  1813.  
  1814.     ReadValue(Buffer,&Value);
  1815.  
  1816.     switch(Value)
  1817.     {
  1818.             /* Terminal status report, return code
  1819.              * for `no malfunction'.
  1820.              */
  1821.  
  1822.         case 5:
  1823.  
  1824.             EmulationSerWrite("\033[0n",-1);
  1825.             break;
  1826.  
  1827.             /* The origin is placed at 0/0 and the first
  1828.              * cursor position is 1/1. We'll have to add
  1829.              * 1 to our internal positions since our
  1830.              * universe has been shifted one field to the
  1831.              * left top corner.
  1832.              */
  1833.  
  1834.         case 6:
  1835.  
  1836.             SPrintf(LocalBuffer,"\033[%ld;%ldR",CursorY + 1,CursorX + 1);
  1837.  
  1838.             EmulationSerWrite(LocalBuffer,-1);
  1839.  
  1840.             break;
  1841.  
  1842.             /* A VT200 command: request printer status.
  1843.              * We will return `the printer is ready' in
  1844.              * case the printer control commands are
  1845.              * enabled, else return `no printer connected'.
  1846.              */
  1847.  
  1848.         case 15:
  1849.  
  1850.             if(Config -> EmulationConfig -> PrinterEnabled)
  1851.                 EmulationSerWrite("\033[?10n",-1);
  1852.             else
  1853.                 EmulationSerWrite("\033[?11n",-1);
  1854.  
  1855.             break;
  1856.  
  1857.             /* VT200 command: request user defined
  1858.              * key status. We will return `user
  1859.              * defined keys are locked'.
  1860.              */
  1861.  
  1862.         case 25:
  1863.  
  1864.             EmulationSerWrite("\033[?21n",-1);
  1865.             break;
  1866.  
  1867.             /* Another VT200 command: request
  1868.              * keyboard language. We will return
  1869.              * `keyboard language unknown'.
  1870.              */
  1871.  
  1872.         case 26:
  1873.  
  1874.             EmulationSerWrite("\033[?27;0n",-1);
  1875.             break;
  1876.     }
  1877. }
  1878.  
  1879.     /* SetSomething(STRPTR Buffer):
  1880.      *
  1881.      *    Set a terminal option.
  1882.      */
  1883.  
  1884. VOID
  1885. SetSomething(STRPTR Buffer)
  1886. {
  1887.     WORD    Value;
  1888.     UBYTE    Last;
  1889.     BOOLEAN    TurnOn;
  1890.  
  1891.     ReadValue(Buffer,&Value);
  1892.     Last = LastChar(Buffer);
  1893.  
  1894.     if(Buffer[1] == '?')
  1895.     {
  1896.         switch(Value)
  1897.         {
  1898.                 /* Set cursor keys applications mode. */
  1899.  
  1900.             case 1:        // DECCKM
  1901.  
  1902.                 if(!Config -> EmulationConfig -> CursorLocked)
  1903.                 {
  1904.                     if(Last == 'h')
  1905.                         Config -> EmulationConfig -> CursorMode = KEYMODE_APPLICATION;
  1906.  
  1907.                     if(Last == 'l')
  1908.                         Config -> EmulationConfig -> CursorMode = KEYMODE_STANDARD;
  1909.                 }
  1910.  
  1911.                 break;
  1912.  
  1913.                 /* ANSI/VT52 mode */
  1914.  
  1915.             case 2:        // DECANM
  1916.  
  1917.                 break;
  1918.  
  1919.                 /* Set line length (132 or 80). */
  1920.  
  1921.             case 3:        // DECCOLM
  1922.  
  1923.                 if(!Config -> EmulationConfig -> FontLocked)
  1924.                 {
  1925.                     if(CursorEnabled)
  1926.                     {
  1927.                         ClearCursor();
  1928.  
  1929.                         TurnOn = TRUE;
  1930.                     }
  1931.                     else
  1932.                         TurnOn = FALSE;
  1933.  
  1934.                     if(Last == 'h')
  1935.                     {
  1936.                         if(CurrentCharWidth != SCALE_HALF)
  1937.                         {
  1938.                             CursorX = CursorY = 0;
  1939.  
  1940.                             RepositionCursor();
  1941.  
  1942.                             BackupRender();
  1943.  
  1944.                             SetAPen(RPort,MappedPens[0][PenTable[0]]);
  1945.  
  1946.                             ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  1947.  
  1948.                             ScrollLineEraseScreen(2);
  1949.  
  1950.                             RasterEraseScreen(2);
  1951.  
  1952.                             SaveConfig(Config,PrivateConfig);
  1953.  
  1954.                             CurrentCharWidth = SCALE_HALF;
  1955.  
  1956.                             BackupRender();
  1957.  
  1958.                             ScreenSizeStuff();
  1959.                         }
  1960.                     }
  1961.  
  1962.                     if(Last == 'l')
  1963.                     {
  1964.                         if(CurrentCharWidth != SCALE_NORMAL)
  1965.                         {
  1966.                             CursorX = CursorY = 0;
  1967.  
  1968.                             RepositionCursor();
  1969.  
  1970.                             BackupRender();
  1971.  
  1972.                             SetAPen(RPort,MappedPens[0][PenTable[0]]);
  1973.  
  1974.                             ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  1975.  
  1976.                             ScrollLineEraseScreen(2);
  1977.  
  1978.                             RasterEraseScreen(2);
  1979.  
  1980.                             SaveConfig(Config,PrivateConfig);
  1981.  
  1982.                             CurrentCharWidth = SCALE_NORMAL;
  1983.  
  1984.                             BackupRender();
  1985.  
  1986.                             ScreenSizeStuff();
  1987.                         }
  1988.                     }
  1989.  
  1990.                     if(TurnOn)
  1991.                         DrawCursor();
  1992.                 }
  1993.  
  1994.                 break;
  1995.  
  1996.                 /* Set scroll mode (jump or smooth). */
  1997.  
  1998.             case 4:        // DECSCLM
  1999.  
  2000.                 if(Last == 'h')
  2001.                     Config -> EmulationConfig -> ScrollMode = SCROLL_SMOOTH;
  2002.  
  2003.                 if(Last == 'l')
  2004.                     Config -> EmulationConfig -> ScrollMode = SCROLL_JUMP;
  2005.  
  2006.                 break;
  2007.  
  2008.                 /* Reverse/normal screen. */
  2009.  
  2010.             case 5:        // DECSCNM
  2011.  
  2012.                 break;
  2013.  
  2014.                 /* Turn region on or off. */
  2015.  
  2016.             case 6:
  2017.  
  2018.                 if(Last == 'h')
  2019.                     UseRegion = TRUE;
  2020.  
  2021.                 if(Last == 'l')
  2022.                     UseRegion = FALSE;
  2023.  
  2024.                 break;
  2025.  
  2026.                 /* Turn character wrapping on or off. */
  2027.  
  2028.             case 7:        // DECAWM
  2029.  
  2030.                 if(!Config -> EmulationConfig -> LockWrapping)
  2031.                 {
  2032.                     if(Last == 'h')
  2033.                         Config -> EmulationConfig -> LineWrap = TRUE;
  2034.  
  2035.                     if(Last == 'l')
  2036.                         Config -> EmulationConfig -> LineWrap = FALSE;
  2037.                 }
  2038.  
  2039.                 break;
  2040.  
  2041.                 /* Turn auto repeat on or off. */
  2042.  
  2043.             case 8:        // DECARM
  2044.  
  2045.                 break;
  2046.  
  2047.                 /* Set 240/480 line mode. */
  2048.  
  2049.             case 9:
  2050.  
  2051.                 break;
  2052.  
  2053.                 /* Print form feed after `print screen command'. */
  2054.  
  2055.             case 18:    // DECPFF
  2056.  
  2057.                 if(Last == 'h')
  2058.                     PrintFormFeed = TRUE;
  2059.  
  2060.                 if(Last == 'l')
  2061.                     PrintFormFeed = FALSE;
  2062.  
  2063.                 break;
  2064.  
  2065.                 /* Print full screen or just region. */
  2066.  
  2067.             case 19:    // DECPEX
  2068.  
  2069.                 if(Last == 'h')
  2070.                     PrintFullScreen = TRUE;
  2071.  
  2072.                 if(Last == 'l')
  2073.                     PrintFullScreen = FALSE;
  2074.  
  2075.                 break;
  2076.  
  2077.                 /* Text cursor enable. */
  2078.  
  2079.             case 25:    // DECTCEM
  2080.  
  2081.                 TurnOn = CursorEnabled;
  2082.  
  2083.                 ClearCursor();
  2084.  
  2085.                 if(Last == 'h')
  2086.                     CursorInvisible = FALSE;
  2087.  
  2088.                 if(Last == 'l')
  2089.                     CursorInvisible = TRUE;
  2090.  
  2091.                 if(TurnOn)
  2092.                     DrawCursor();
  2093.  
  2094.                 break;
  2095.  
  2096.                 /* National/multinational character set. */
  2097.  
  2098.             case 42:    // DECNRCM
  2099.  
  2100.                 break;
  2101.         }
  2102.     }
  2103.     else
  2104.     {
  2105.         switch(Value)
  2106.         {
  2107.                 /* Keyboard action unlocked/locked. */
  2108.  
  2109.             case 2:        // KAM
  2110.  
  2111.                 break;
  2112.  
  2113.                 /* Insertion/replacement. */
  2114.  
  2115.             case 4:        // IRM
  2116.  
  2117.                 if(Last == 'h')
  2118.                     Config -> EmulationConfig -> InsertMode = TRUE;
  2119.  
  2120.                 if(Last == 'l')
  2121.                     Config -> EmulationConfig -> InsertMode = FALSE;
  2122.  
  2123.                 break;
  2124.  
  2125.                 /* Echo on/off. */
  2126.  
  2127.             case 12:    // SRM
  2128.  
  2129.                 if(Last == 'h')
  2130.                     Config -> SerialConfig -> Duplex = DUPLEX_FULL;
  2131.  
  2132.                 if(Last == 'l')
  2133.                     Config -> SerialConfig -> Duplex = DUPLEX_HALF;
  2134.  
  2135.                 break;
  2136.  
  2137.                 /* Line feed/new line. */
  2138.  
  2139.             case 20:    // LNM
  2140.  
  2141.                 if(Last == 'h')
  2142.                     Config -> EmulationConfig -> NewLineMode = TRUE;
  2143.  
  2144.                 if(Last == 'l')
  2145.                     Config -> EmulationConfig -> NewLineMode = FALSE;
  2146.  
  2147.                 break;
  2148.         }
  2149.     }
  2150. }
  2151.  
  2152.     /* NumericAppMode(STRPTR Buffer):
  2153.      *
  2154.      *    Set the numeric pad applications mode.
  2155.      */
  2156.  
  2157. VOID
  2158. NumericAppMode(STRPTR Buffer)
  2159. {
  2160.     if(!Config -> EmulationConfig -> KeysLocked)
  2161.     {
  2162.         if(*Buffer == '=')
  2163.             Config -> EmulationConfig -> NumericMode = KEYMODE_APPLICATION;
  2164.         else
  2165.         {
  2166.             if(*Buffer == '>')
  2167.                 Config -> EmulationConfig -> NumericMode = KEYMODE_STANDARD;
  2168.         }
  2169.     }
  2170. }
  2171.  
  2172.     /* MoveCursor(STRPTR Buffer):
  2173.      *
  2174.      *    Move the cursor in some direction and stop at
  2175.      *    top/bottom/margin if necessary.
  2176.      */
  2177.  
  2178. VOID
  2179. MoveCursor(STRPTR Buffer)
  2180. {
  2181.     WORD Value,Hit;
  2182.     BYTE InRegion = TRUE;
  2183.  
  2184.     ReadValue(Buffer,&Value);
  2185.  
  2186.     if(Value < 1)
  2187.         Value = 1;
  2188.  
  2189.     switch(LastChar(Buffer))
  2190.     {
  2191.             /* Move cursor Up value lines */
  2192.  
  2193.         case 'A':
  2194.  
  2195. ScrollUp:        Hit = 0;
  2196.  
  2197.             if(RegionSet)
  2198.             {
  2199.                 if(CursorY >= Top)
  2200.                     Hit = Top;
  2201.                 else
  2202.                     InRegion = FALSE;
  2203.             }
  2204.  
  2205.             CursorY -= Value;
  2206.  
  2207.             if(CursorY < Hit)
  2208.             {
  2209.                 Value = CursorY - Hit;
  2210.  
  2211.                 CursorY = Hit;
  2212.  
  2213.                 if(Config -> EmulationConfig -> CursorWrap && InRegion)
  2214.                     ScrollRegion(Value);
  2215.             }
  2216.  
  2217.             ConFontScaleUpdate();
  2218.  
  2219.             break;
  2220.  
  2221.             /* Move cursor Down value lines */
  2222.  
  2223.         case 'B':
  2224.  
  2225. ScrollDown:        Hit = LastLine;
  2226.  
  2227.             if(RegionSet)
  2228.             {
  2229.                 if(CursorY <= Bottom)
  2230.                     Hit = Bottom;
  2231.                 else
  2232.                     InRegion = FALSE;
  2233.             }
  2234.  
  2235.             CursorY += Value;
  2236.  
  2237.             if(CursorY > Hit)
  2238.             {
  2239.                 Value = CursorY - Hit;
  2240.  
  2241.                 CursorY = Hit;
  2242.  
  2243.                 if(Config -> EmulationConfig -> CursorWrap && InRegion)
  2244.                     ScrollRegion(Value);
  2245.             }
  2246.  
  2247.             ConFontScaleUpdate();
  2248.  
  2249.             break;
  2250.  
  2251.             /* Move cursor Right value columns */
  2252.  
  2253.         case 'C':
  2254.  
  2255.             CursorX += Value;
  2256.  
  2257.             if(CursorX > LastPrintableColumn)
  2258.             {
  2259.                 if(Config -> EmulationConfig -> CursorWrap)
  2260.                 {
  2261.                     Value = CursorX / (LastPrintableColumn + 1);
  2262.  
  2263.                     CursorX    -= Value * (LastPrintableColumn + 1);
  2264.  
  2265.                     goto ScrollDown;
  2266.                 }
  2267.                 else
  2268.                     CursorX = LastPrintableColumn;
  2269.             }
  2270.  
  2271.             break;
  2272.  
  2273.             /* Move cursor Left value columns */
  2274.  
  2275.         case 'D':
  2276.  
  2277.             CursorX -= Value;
  2278.  
  2279.             if(CursorX < 0)
  2280.             {
  2281.                 if(Config -> EmulationConfig -> CursorWrap)
  2282.                 {
  2283.                     Value     = CursorX / (LastPrintableColumn + 1);
  2284.                     CursorX    -= Value * (LastPrintableColumn + 1);
  2285.                     Value     = -Value;
  2286.  
  2287.                     goto ScrollDown;
  2288.                 }
  2289.                 else
  2290.                     CursorX = 0;
  2291.             }
  2292.  
  2293.             break;
  2294.     }
  2295.  
  2296.     if(CursorX > LastPrintableColumn)
  2297.         CursorX = LastPrintableColumn;
  2298.  
  2299.     RepositionCursor();
  2300. }
  2301.  
  2302.     /* MoveColumn(STRPTR Buffer):
  2303.      *
  2304.      *    Move the cursor to a certain column.
  2305.      */
  2306.  
  2307. VOID
  2308. MoveColumn(STRPTR Buffer)
  2309. {
  2310.     WORD Value;
  2311.  
  2312.     ReadValue(Buffer,&Value);
  2313.  
  2314.     if(Value < 1)
  2315.         Value = 1;
  2316.  
  2317.     CursorX = Value - 1;
  2318.  
  2319.     if(CursorX < 0)
  2320.         CursorX = 0;
  2321.  
  2322.     if(CursorX > LastPrintableColumn)
  2323.         CursorX = LastPrintableColumn;
  2324.  
  2325.     RepositionCursor();
  2326. }
  2327.  
  2328.     /* EraseLine(STRPTR Buffer):
  2329.      *
  2330.      *    Erase a line on the display.
  2331.      */
  2332.  
  2333. VOID
  2334. EraseLine(STRPTR Buffer)
  2335. {
  2336.     WORD Value,Width = GetFontWidth();
  2337.  
  2338.     if(*Buffer == '?')
  2339.         Buffer++;
  2340.  
  2341.     ReadValue(Buffer,&Value);
  2342.  
  2343.     BackupRender();
  2344.  
  2345.     switch(Value)
  2346.     {
  2347.         case 1:
  2348.  
  2349.             if(CursorX)
  2350.                 ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY),CursorX * Width - 1,MUL_Y(CursorY + 1) - 1);
  2351.  
  2352.             break;
  2353.  
  2354.         case 2:
  2355.  
  2356.             ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2357.             break;
  2358.  
  2359.         default:
  2360.  
  2361.             ScrollLineRectFillNoTabChange(RPort,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2362.             break;
  2363.     }
  2364.  
  2365.     ScrollLineEraseLine(Value);
  2366.  
  2367.     RasterEraseLine(Value);
  2368.  
  2369.     BackupRender();
  2370. }
  2371.  
  2372.     /* EraseScreen(STRPTR Buffer):
  2373.      *
  2374.      *    Erase parts of the screen.
  2375.      */
  2376.  
  2377. VOID
  2378. EraseScreen(STRPTR Buffer)
  2379. {
  2380.     WORD Value,Width = GetFontWidth();
  2381.  
  2382.     if(*Buffer == '?')
  2383.         Buffer++;
  2384.  
  2385.     ReadValue(Buffer,&Value);
  2386.  
  2387.     BackupRender();
  2388.  
  2389.     switch(Value)
  2390.     {
  2391.         case 1:
  2392.  
  2393.             if(CursorY)
  2394.                 ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(CursorY) - 1);
  2395.  
  2396.             if(CursorX)
  2397.                 ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY),CursorX * Width - 1,MUL_Y(CursorY + 1) - 1);
  2398.  
  2399.             break;
  2400.  
  2401.         case 2:
  2402.  
  2403.             ScrollLineRectFillNoTabChange(RPort,0,0,LastPixel,MUL_Y(LastLine + 1) - 1);
  2404.  
  2405.             if(Config -> EmulationConfig -> CLSResetsCursor)
  2406.                 CursorX = CursorY = 0;
  2407.  
  2408.             break;
  2409.  
  2410.         default:
  2411.  
  2412.             ScrollLineRectFillNoTabChange(RPort,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1);
  2413.  
  2414.             if(CursorY != LastLine)
  2415.                 ScrollLineRectFillNoTabChange(RPort,0,MUL_Y(CursorY + 1),LastPixel,MUL_Y(LastLine + 1) - 1);
  2416.  
  2417.             break;
  2418.     }
  2419.  
  2420.     ScrollLineEraseScreen(Value);
  2421.  
  2422.     RasterEraseScreen(Value);
  2423.  
  2424.     BackupRender();
  2425. }
  2426.  
  2427.     /* EraseCharacters(STRPTR Buffer):
  2428.      *
  2429.      *    Erase a number of characters.
  2430.      */
  2431.  
  2432. VOID
  2433. EraseCharacters(STRPTR Buffer)
  2434. {
  2435.     WORD Value,Width = GetFontWidth();
  2436.  
  2437.     if(*Buffer == '?')
  2438.         Buffer++;
  2439.  
  2440.     ReadValue(Buffer,&Value);
  2441.  
  2442.     BackupRender();
  2443.  
  2444.     if(Value < 1)
  2445.         Value = 1;
  2446.  
  2447.     if(Value > LastPrintableColumn)
  2448.         Value = LastPrintableColumn;
  2449.  
  2450.     RasterEraseCharacters(Value);
  2451.  
  2452.     ScrollLineRasterNoTabChange(RPort,Value * Width,0,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1,FALSE);
  2453.  
  2454.     ScrollLineEraseCharacters(Value);
  2455.  
  2456.     BackupRender();
  2457. }
  2458.  
  2459.     /* InsertCharacters(STRPTR Buffer):
  2460.      *
  2461.      *    Insert a number of characters.
  2462.      */
  2463.  
  2464. VOID
  2465. InsertCharacters(STRPTR Buffer)
  2466. {
  2467.     WORD Value,Width = GetFontWidth();
  2468.  
  2469.     ReadValue(Buffer,&Value);
  2470.  
  2471.     BackupRender();
  2472.  
  2473.     if(Value < 1)
  2474.         Value = 1;
  2475.  
  2476.     if(CursorX + Value > LastPrintableColumn)
  2477.         Value = LastPrintableColumn - CursorX;
  2478.  
  2479.     if(Value > 0)
  2480.     {
  2481.         RasterShiftChar(Value);
  2482.  
  2483.         ScrollLineRasterNoTabChange(RPort,-Value * Width,0,CursorX * Width,MUL_Y(CursorY),LastPixel,MUL_Y(CursorY + 1) - 1,FALSE);
  2484.  
  2485.         ScrollLineShiftChar(Value);
  2486.     }
  2487.  
  2488.     BackupRender();
  2489. }
  2490.  
  2491.     /* InsertLine(STRPTR Buffer):
  2492.      *
  2493.      *    Insert a number of lines and scroll the rest of the
  2494.      *    display down.
  2495.      */
  2496.  
  2497. VOID
  2498. InsertLine(STRPTR Buffer)
  2499. {
  2500.     WORD Value,RegionBottom,RegionTop,TheTop = CursorY;
  2501.  
  2502.     ReadValue(Buffer,&Value);
  2503.  
  2504.     BackupRender();
  2505.  
  2506.     SetAPen(RPort,MappedPens[0][PenTable[0]]);
  2507.  
  2508.     if(Value < 1)
  2509.         Value = 1;
  2510.  
  2511.     if(RegionSet)
  2512.     {
  2513.         RegionTop    = Top;
  2514.         RegionBottom    = Bottom + 1;
  2515.     }
  2516.     else
  2517.     {
  2518.         RegionTop    = 0;
  2519.         RegionBottom    = LastLine + 1;
  2520.     }
  2521.  
  2522.     if(TheTop < RegionTop)
  2523.         TheTop = RegionTop;
  2524.  
  2525.     if(TheTop + Value > RegionBottom)
  2526.         Value = RegionBottom - TheTop;
  2527.  
  2528.     if(Value > 0)
  2529.     {
  2530.         RasterInsertLine(Value,TheTop);
  2531.  
  2532.         ScrollLineRaster(RPort,0,-MUL_Y(Value),0,MUL_Y(TheTop),LastPixel,MUL_Y(RegionBottom) - 1,FALSE);
  2533.     }
  2534.  
  2535.     BackupRender();
  2536. }
  2537.  
  2538.     /* ClearLine(STRPTR Buffer):
  2539.      *
  2540.      *    Clear a number of lines and scroll up the ones below it.
  2541.      */
  2542.  
  2543. VOID
  2544. ClearLine(STRPTR Buffer)
  2545. {
  2546.     WORD Value,RegionBottom,RegionTop,TheTop = CursorY;
  2547.  
  2548.     ReadValue(Buffer,&Value);
  2549.  
  2550.     BackupRender();
  2551.  
  2552.     SetAPen(RPort,MappedPens[0][PenTable[0]]);
  2553.  
  2554.     if(Value < 1)
  2555.         Value = 1;
  2556.  
  2557.     if(RegionSet)
  2558.     {
  2559.         RegionTop    = Top;
  2560.         RegionBottom    = Bottom + 1;
  2561.     }
  2562.     else
  2563.     {
  2564.         RegionTop    = 0;
  2565.         RegionBottom    = LastLine + 1;
  2566.     }
  2567.  
  2568.     if(TheTop < RegionTop)
  2569.         TheTop = RegionTop;
  2570.  
  2571.     if(TheTop + Value > RegionBottom)
  2572.         Value = RegionBottom - TheTop;
  2573.  
  2574.     if(Value > 0)
  2575.     {
  2576.         RasterClearLine(Value,TheTop);
  2577.  
  2578.         ScrollLineRaster(RPort,0,MUL_Y(Value),0,MUL_Y(TheTop),LastPixel,MUL_Y(RegionBottom) - 1,FALSE);
  2579.     }
  2580.  
  2581.     BackupRender();
  2582. }
  2583.  
  2584.     /* SetTabs(STRPTR Buffer):
  2585.      *
  2586.      *    Set the current tab stops.
  2587.      */
  2588.  
  2589. VOID
  2590. SetTabs(STRPTR Buffer)
  2591. {
  2592.     WORD Value;
  2593.  
  2594.     ReadValue(Buffer,&Value);
  2595.  
  2596.     if(Value < 1)
  2597.         Value = 0;
  2598.  
  2599.     switch(Value)
  2600.     {
  2601.         case 0:
  2602.  
  2603.             if(CursorX < TabStopMax)
  2604.                 TabStops[CursorX] = FALSE;
  2605.  
  2606.             break;
  2607.  
  2608.         case 3:
  2609.  
  2610.             memset(TabStops,FALSE,TabStopMax);
  2611.  
  2612.             break;
  2613.  
  2614.         default:
  2615.  
  2616.             break;
  2617.     }
  2618. }
  2619.  
  2620.     /* SetAbsolutePosition(STRPTR Buffer):
  2621.      *
  2622.      *    Move the cursor to a given location on the display,
  2623.      *    this routine ignores the current scroll region
  2624.      *    settings.
  2625.      */
  2626.  
  2627. VOID
  2628. SetAbsolutePosition(STRPTR Buffer)
  2629. {
  2630.     WORD Value;
  2631.  
  2632.     Buffer = ReadValue(Buffer,&Value);
  2633.  
  2634.     CursorY = 0;
  2635.     CursorX = 0;
  2636.  
  2637.     if(Value == -1)
  2638.         ConFontScaleUpdate();
  2639.     else
  2640.     {
  2641.             /* Our raster origin is 0/0 instead of 1/1. */
  2642.  
  2643.         if(Value)
  2644.             Value--;
  2645.  
  2646.         CursorY = Value;
  2647.  
  2648.         if(Buffer)
  2649.         {
  2650.             ReadValue(Buffer,&Value);
  2651.  
  2652.             if(Value > 0)
  2653.                 CursorX = Value - 1;
  2654.             else
  2655.                 CursorX = 0;
  2656.         }
  2657.  
  2658.             /* Truncate illegal positions. */
  2659.  
  2660.         if(CursorY > LastLine)
  2661.             CursorY = LastLine;
  2662.  
  2663.         ConFontScaleUpdate();
  2664.  
  2665.         if(CursorX > LastPrintableColumn)
  2666.             CursorX = LastPrintableColumn;
  2667.     }
  2668.  
  2669.     RepositionCursor();
  2670. }
  2671.  
  2672.     /* SetTopPosition(STRPTR Buffer):
  2673.      *
  2674.      *    Move the cursor to a given location on the display,
  2675.      *    this routine respects the current scroll region
  2676.      *    settings.
  2677.      */
  2678.  
  2679. VOID
  2680. SetTopPosition(STRPTR Buffer)
  2681. {
  2682.     WORD Value;
  2683.  
  2684.     Buffer = ReadValue(Buffer,&Value);
  2685.  
  2686.     if(UseRegion && RegionSet)
  2687.         CursorY = Top;
  2688.     else
  2689.         CursorY = 0;
  2690.  
  2691.     CursorX = 0;
  2692.  
  2693.     if(Value == -1)
  2694.         ConFontScaleUpdate();
  2695.     else
  2696.     {
  2697.             /* Our raster origin is 0/0 instead of 1/1. */
  2698.  
  2699.         if(Value)
  2700.             Value--;
  2701.  
  2702.         if(UseRegion && RegionSet)
  2703.             CursorY = Top + Value;
  2704.         else
  2705.             CursorY = Value;
  2706.  
  2707.         if(Buffer)
  2708.         {
  2709.             ReadValue(Buffer,&Value);
  2710.  
  2711.             if(Value > 0)
  2712.                 CursorX = Value - 1;
  2713.             else
  2714.                 CursorX = 0;
  2715.         }
  2716.  
  2717.             /* Truncate illegal positions. */
  2718.  
  2719.         if(CursorY > LastLine)
  2720.             CursorY = LastLine;
  2721.  
  2722.         ConFontScaleUpdate();
  2723.  
  2724.         if(CursorX > LastPrintableColumn)
  2725.             CursorX = LastPrintableColumn;
  2726.     }
  2727.  
  2728.     RepositionCursor();
  2729. }
  2730.  
  2731.     /* SetAttributes(STRPTR Buffer):
  2732.      *
  2733.      *    Set the current display rendering attributes.
  2734.      */
  2735.  
  2736. VOID
  2737. SetAttributes(STRPTR Buffer)
  2738. {
  2739.     WORD Value;
  2740.  
  2741.     do
  2742.     {
  2743.         Buffer = ReadValue(Buffer,&Value);
  2744.  
  2745.         if(Value == -1)
  2746.             Value = 0;
  2747.  
  2748.         switch(Value)
  2749.         {
  2750.             case 0:
  2751.  
  2752.                 if(!Config -> EmulationConfig -> LockColour)
  2753.                 {
  2754.                     ForegroundPen = GetPenIndex(SafeTextPen);
  2755.                     BackgroundPen = 0;
  2756.                 }
  2757.  
  2758.                 if(!Config -> EmulationConfig -> LockStyle)
  2759.                     Attributes = 0;
  2760.  
  2761.                 break;
  2762.  
  2763.             case 1:
  2764.  
  2765.                 if(!Config -> EmulationConfig -> LockStyle)
  2766.                     Attributes |= ATTR_HIGHLIGHT;
  2767.  
  2768.                 break;
  2769.  
  2770.             case 4:
  2771.  
  2772.                 if(!Config -> EmulationConfig -> LockStyle)
  2773.                     Attributes |= ATTR_UNDERLINE;
  2774.  
  2775.                 break;
  2776.  
  2777.             case 5:
  2778.  
  2779.                 if(!Config -> EmulationConfig -> LockStyle)
  2780.                     Attributes |= ATTR_BLINK;
  2781.  
  2782.                 break;
  2783.  
  2784.             case 7:
  2785.  
  2786.                 if(!Config -> EmulationConfig -> LockStyle)
  2787.                     Attributes |= ATTR_INVERSE;
  2788.  
  2789.                 break;
  2790.  
  2791.             case 22:
  2792.  
  2793.                 if(!Config -> EmulationConfig -> LockStyle)
  2794.                     Attributes &= ~ATTR_HIGHLIGHT;
  2795.  
  2796.                 break;
  2797.  
  2798.             case 24:
  2799.  
  2800.                 if(!Config -> EmulationConfig -> LockStyle)
  2801.                     Attributes &= ~ATTR_UNDERLINE;
  2802.  
  2803.                 break;
  2804.  
  2805.             case 25:
  2806.  
  2807.                 if(!Config -> EmulationConfig -> LockStyle)
  2808.                     Attributes &= ~ATTR_BLINK;
  2809.  
  2810.                 break;
  2811.  
  2812.             case 27:
  2813.  
  2814.                 if(!Config -> EmulationConfig -> LockStyle)
  2815.                     Attributes &= ~ATTR_INVERSE;
  2816.  
  2817.                 break;
  2818.  
  2819.             default:
  2820.  
  2821.                 if(!Config -> EmulationConfig -> LockColour)
  2822.                 {
  2823.                     if(Value >= 30)
  2824.                     {
  2825.                         if(Value <= 37)
  2826.                             ForegroundPen = Value - 30;
  2827.                         else
  2828.                         {
  2829.                             if(Value >= 40 && Value <= 47)
  2830.                                 BackgroundPen = Value - 40;
  2831.                         }
  2832.                     }
  2833.                 }
  2834.  
  2835.                 break;
  2836.         }
  2837.     }
  2838.     while(Buffer);
  2839.  
  2840.     UpdatePens();
  2841.  
  2842.     RepositionCursor();
  2843. }
  2844.  
  2845.     /* SetRegion(STRPTR Buffer):
  2846.      *
  2847.      *    Set the current scroll region top and bottom.
  2848.      */
  2849.  
  2850. VOID
  2851. SetRegion(STRPTR Buffer)
  2852. {
  2853.     WORD NewTop,Value,NewBottom = LastLine;
  2854.  
  2855.     Buffer = ReadValue(Buffer,&Value);
  2856.  
  2857.     if(!Value)
  2858.         Value = 1;
  2859.  
  2860.     if(Value > 0)
  2861.     {
  2862.         if(Buffer)
  2863.         {
  2864.             NewTop = Value - 1;
  2865.  
  2866.             ReadValue(Buffer,&Value);
  2867.  
  2868.             if(Value > 0)
  2869.                 NewBottom = Value - 1;
  2870.  
  2871.             if(NewBottom > LastLine)
  2872.                 NewBottom = LastLine;
  2873.  
  2874.             if(NewTop > LastLine)
  2875.                 NewTop = LastLine;
  2876.         }
  2877.         else
  2878.         {
  2879.             NewTop        = 0;
  2880.             NewBottom    = LastLine;
  2881.         }
  2882.     }
  2883.     else
  2884.     {
  2885.         NewTop        = 0;
  2886.         NewBottom    = LastLine;
  2887.     }
  2888.  
  2889.     if(NewTop < NewBottom)
  2890.     {
  2891.         if(NewTop != 0 || NewBottom != LastLine)
  2892.         {
  2893.             Top    = NewTop;
  2894.             Bottom    = NewBottom;
  2895.  
  2896.             RegionSet = TRUE;
  2897.         }
  2898.         else
  2899.             UseRegion = RegionSet = FALSE;
  2900.  
  2901.         ResetCursor();
  2902.     }
  2903.     else
  2904.         RegionSet = FALSE;
  2905. }
  2906.  
  2907.     /* ResetCursor():
  2908.      *
  2909.      *    Reset cursor to top of screen.
  2910.      */
  2911.  
  2912. VOID
  2913. ResetCursor()
  2914. {
  2915.     CursorX    = 0;
  2916.  
  2917.     if(UseRegion && RegionSet)
  2918.         CursorY = Top;
  2919.     else
  2920.         CursorY    = 0;
  2921.  
  2922.     ConFontScaleUpdate();
  2923.  
  2924.     RepositionCursor();
  2925. }
  2926.  
  2927.     /* MoveCursorUp(STRPTR Buffer):
  2928.      *
  2929.      *    Move the cursor up <n> lines, scroll the screen
  2930.      *    contents if necessary.
  2931.      */
  2932.  
  2933. VOID
  2934. MoveCursorUp(STRPTR Buffer)
  2935. {
  2936.     WORD Value,i;
  2937.  
  2938.     ReadValue(Buffer,&Value);
  2939.  
  2940.     if(Value < 1)
  2941.         Value = 1;
  2942.  
  2943.     for(i = 0 ; i < Value ; i++)
  2944.         CursorScrollUp();
  2945.  
  2946.     CursorX = 0;
  2947.  
  2948.     RepositionCursor();
  2949. }
  2950.  
  2951.     /* MoveCursorDown(STRPTR Buffer):
  2952.      *
  2953.      *    Move the cursor down <n> lines, scroll the screen
  2954.      *    contents if necessary.
  2955.      */
  2956.  
  2957. VOID
  2958. MoveCursorDown(STRPTR Buffer)
  2959. {
  2960.     WORD Value,i;
  2961.  
  2962.     ReadValue(Buffer,&Value);
  2963.  
  2964.     if(Value < 1)
  2965.         Value = 1;
  2966.  
  2967.     for(i = 0 ; i < Value ; i++)
  2968.         DownLine();
  2969.  
  2970.     CursorX = 0;
  2971.  
  2972.     RepositionCursor();
  2973. }
  2974.